#include "Base/Timestamp.h"

namespace toym
{

Timestamp::Timestamp(std::int64_t ticks)
    : m_microseconds(ticks)
{}

std::int64_t Timestamp::getTick() const {
    return m_microseconds;
}

bool Timestamp::isValid() const {
    return m_microseconds > 0;
}

void Timestamp::toStructTm(struct tm* ptm) const {
    if (nullptr != ptm) {
        time_t curTime = m_microseconds / s_tickPerSecond;
        ::gmtime_r(&curTime, ptm);
    }
}

std::string Timestamp::toString() const {
    struct tm stm;
    std::string ret;
    time_t curTime = m_microseconds/s_tickPerSecond;
    char buf[64];
    size_t n = 0;

    ::gmtime_r(&curTime, &stm);
    n = strftime(buf, sizeof(buf), "%Y-%m-%d %T", &stm);
    if (n == 0) {
        ret.append("ErrorTime");
        return ret;
    }
    ret.append(buf);
    snprintf(buf, sizeof(buf), ".%06ldz", m_microseconds%s_tickPerSecond);
    ret.append(buf);
    return ret;
}

std::string Timestamp::toFormatString() const {
    return toString();
}

Timestamp Timestamp::now() {
    struct timespec ts;
    ::clock_gettime(CLOCK_REALTIME, &ts);
    return Timestamp(Timestamp::s_tickPerSecond*ts.tv_sec + ts.tv_nsec/1000);
}

Timestamp Timestamp::millionsecond(std::int64_t millionseconds) {
    return Timestamp(millionseconds*1000);
}

Timestamp Timestamp::second(std::int64_t seconds) {
    return Timestamp(seconds*s_tickPerSecond);
}

Timestamp Timestamp::minute(std::int64_t minutes) {
    return Timestamp(minutes*60*s_tickPerSecond);
}

Timestamp Timestamp::hour(std::int64_t hours) {
    return Timestamp(hours*24*60*s_tickPerSecond);
}

Timestamp operator+(Timestamp lhs, Timestamp rhs) {
    return Timestamp(lhs.getTick() + rhs.getTick());
}

Timestamp operator-(Timestamp lhs, Timestamp rhs) {
    return Timestamp(lhs.getTick() - rhs.getTick());
}

bool operator==(Timestamp lhs, Timestamp rhs) {
    return lhs.getTick() == rhs.getTick();
}

bool operator<(Timestamp lhs, Timestamp rhs) {
    return lhs.getTick() < rhs.getTick();
}

bool operator>(Timestamp lhs, Timestamp rhs) {
    return lhs.getTick() > rhs.getTick();
}

bool operator<=(Timestamp lhs, Timestamp rhs) {
    return lhs < rhs || lhs == rhs;
}

bool operator>=(Timestamp lhs, Timestamp rhs) {
    return lhs > rhs || lhs == rhs;
}

} // namespace mylib
